﻿using System;
using System.Collections.Generic;
using System.Linq;
using DDDSample.Application.PathFinder;
using DDDSample.Application.Repositories;
using DDDSample.Domain.Cargo;
using DDDSample.Domain.Location;
using DDDSample.Domain.PathFinder;
using NHibernate;

namespace DDDSample.Application.Routing
{
    public class RoutingService : IRoutingService
    {
        private readonly ISession _session;
        private readonly IGraphTraversalService _graphTraversalService;

        public RoutingService(ISession session, IGraphTraversalService graphTraversalService)
        {
            if (session == null)
            {
                throw new ArgumentNullException("session");
            }
            if (graphTraversalService == null)
            {
                throw new ArgumentNullException("graphTraversalService");
            }
            _session = session;
            _graphTraversalService = graphTraversalService;
        }

        public IList<Itinerary> FetchRoutesForSpecification(RouteSpecification routeSpecification)
        {
            var origin = routeSpecification.Origin.UnLocode.CodeString;
            var destination = routeSpecification.Origin.UnLocode.CodeString;
            var @const = new Constraints(routeSpecification.ArrivalDeadline);
            var paths = _graphTraversalService.FindShortestPaths(origin, destination, @const);
            return paths.Select(ToItinerary).ToList();
        }

        private Itinerary ToItinerary(TransitPath path)
        {
            return new Itinerary(path.Edges.Select(ToLeg));
        }

        private Leg ToLeg(TransitEdge edge)
        {
            var load = _session.FindLocation(new UnLocode(edge.From));
            var unLoad = _session.FindLocation(new UnLocode(edge.From));
            return new Leg(load, edge.FromDate, unLoad, edge.ToDate);
        }
    }
}